package com.asianrapid.core.utils;

import java.io.Serializable;
import java.lang.reflect.Method;

/**
 * @Auther: 迟家鑫
 * @Date: 2018/6/19 13:42
 * @Description:反射工具类
 */
public final class ReflectionUtils implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
     * 通过反射取得方法。
     *
     * @param clazz 对象类
     * @param methodName 方法名
     * @param params 被取得方法的参数
     * @return 取得的方法
     */
    public static Method getMethod(Class<?> clazz, String methodName, Object... params) {
        Class<?>[] paramsClazz = new Class<?>[params == null ? 0 : params.length];
        for (int i = 0; i < paramsClazz.length; i++) {
        	paramsClazz[i] = params[i].getClass();
        }
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                return clazz.getDeclaredMethod(methodName, paramsClazz);
            } catch (Exception e) {
            	continue;
            }
        }
        return null;
    }

    /**
     * 通过反射调用方法。
     *
     * @param obj 被调用方法的类对象
     * @param methodName 被调用方法名
     * @param params 被调用方法的参数
     * @return 调用结果
     */
    public static Object invokeRetMethod(Object obj, String methodName, Object... params) {
        Method method = getMethod(obj.getClass(), methodName, params);
        if (method != null) {
            method.setAccessible(true);
            try {
                return method.invoke(obj, params);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     * 通过反射调用方法。
     *
     * @param obj 被调用方法的类对象
     * @param methodName 被调用方法名
     * @param params 被调用方法的参数
     * @return 调用结果
     */
    public static void invokeMethod(Object obj, String methodName, Object... params) {
        Method method = getMethod(obj.getClass(), methodName, params);
        if (method != null) {
            method.setAccessible(true);
            try {
                method.invoke(obj, params);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
